package com.marvels.approve.process.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.dragon.app.ykd.constant.ApplyNode;
import com.dragon.app.ykd.service.AcLoanApplyNodeService;
import com.dragon.loan.service.LoanInfoIDragonService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.util.StringUtil;
import com.marvels.approve.common.dto.InsurancePolicyDTO;
import com.marvels.approve.common.service.ApproveSharedDataService;
import com.marvels.approve.common.service.ISysUserService;
import com.marvels.approve.common.service.McamLoanApplyInfoCommonService;
import com.marvels.approve.consum.ApproveConsumerExternalApi;
import com.marvels.approve.consum.ApproveConsumerFinancialApi;
import com.marvels.approve.consum.ApproveConsumerProductApi;
import com.marvels.approve.consum.ApproveConsumerSystemApi;
import com.marvels.approve.loan.dao.ApprovalResultsDao;
import com.marvels.approve.loan.dao.IMcamLoanApplyInfoDao;
import com.marvels.approve.loan.dao.McamLoanInsurancePolicyInfoMapper;
import com.marvels.approve.loan.dto.LoanAfterInfoDTO;
import com.marvels.approve.loan.dto.McamAutoDecisionWithBLOBs;
import com.marvels.approve.loan.dto.McamLoanApplyInfoDTO;
import com.marvels.approve.loan.dto.McptConsultingFeeDTO;
import com.marvels.approve.loan.dto.McptProductType;
import com.marvels.approve.loan.dto.McptProductTypeDto;
import com.marvels.approve.loan.dto.McsmSystemParam;
import com.marvels.approve.loan.service.IMcamLoanApplyInfoService;
import com.marvels.approve.loan.service.LoanRiskTipsService;
import com.marvels.approve.manager.dto.ActivitiNodeDTO;
import com.marvels.approve.manager.dto.CaseManagerProductTypeDTO;
import com.marvels.approve.manager.dto.CaseNodeRoleDTO;
import com.marvels.approve.manager.dto.LoanStateEnum;
import com.marvels.approve.manager.service.IActivityLoadingService;
import com.marvels.approve.manager.service.ICaseManagerProductTypeService;
import com.marvels.approve.manager.service.ICaseNodeRoleService;
import com.marvels.approve.mqueues.service.ApproveILoanApplyMqProduct;
import com.marvels.approve.process.api.LoanBasicDataConsumerApi;
import com.marvels.approve.process.api.MarvelDecisionApi;
import com.marvels.approve.process.dao.HousePropertyDao;
import com.marvels.approve.process.dao.ILoanApplyCaseDao;
import com.marvels.approve.process.dao.McamHousePropertyDao;
import com.marvels.approve.process.dto.CompleteProcessDTO;
import com.marvels.approve.process.dto.DecisionMsgDTO;
import com.marvels.approve.process.dto.DecisionRefusListDTO;
import com.marvels.approve.process.dto.HandleProcessDTO;
import com.marvels.approve.process.dto.HungUpConditionDTO;
import com.marvels.approve.process.dto.IntBankCreditCard;
import com.marvels.approve.process.dto.IntBankCredittips;
import com.marvels.approve.process.dto.IntBankNotCredittips;
import com.marvels.approve.process.dto.IntBankNotPinshouseholds;
import com.marvels.approve.process.dto.LoanApplyCaseDTO;
import com.marvels.approve.process.dto.LoanApplyCaseLogDTO;
import com.marvels.approve.process.dto.McamHousePropertyDTO;
import com.marvels.approve.process.dto.McptCustomerTypeParamDTO;
import com.marvels.approve.process.dto.McptManagementFeeDTO;
import com.marvels.approve.process.dto.McptProduct;
import com.marvels.approve.process.dto.McptProductFundRelationDto;
import com.marvels.approve.process.dto.McptProductMappedDto;
import com.marvels.approve.process.dto.ProcessApproveDTO;
import com.marvels.approve.process.dto.RiskParamsDTO;
import com.marvels.approve.process.dto.RiskResultDTO;
import com.marvels.approve.process.dto.SysUserDTO;
import com.marvels.approve.process.dto.SysUserRoleDTO;
import com.marvels.approve.process.service.ILoanApplyCaseLogService;
import com.marvels.approve.process.service.ILoanApplyCaseService;
import com.marvels.approve.process.service.IProcessService;
import com.marvels.common.constants.ApplyCaseStatusConstant;
import com.marvels.common.constants.CaseNodeConstant;
import com.marvels.common.constants.FundSource;
import com.marvels.common.constants.LoanCaseStatusConstant;
import com.marvels.common.constants.LoanStateConstant;
import com.marvels.common.constants.MarvelsConstant;
import com.marvels.common.constants.PatternType;
import com.marvels.common.dto.MarvelsResultDTO;
import com.marvels.common.dto.UserDTO;
import com.marvels.common.exception.MarvelsBusinessException;
import com.marvels.common.utils.CacheUtils;
import com.marvels.common.utils.CommonProperties;
import com.marvels.common.utils.DateUtils;
import com.marvels.common.utils.MarvelsLogUtil;
import com.marvels.common.utils.MarvelsUtils;
import com.marvels.common.utils.ServerProperties;



/**
 * 工单跟踪服务
 * 
 * @author 何杰 2018年4月11日
 */
@Service
public class LoanApplyCaseServiceImpl implements ILoanApplyCaseService {
	@Value("${config.properties.path}")
	private String configPropertiesPath;
	
//	@Autowired
//	private CommonProperties commonProperties;
	@Autowired
	private ILoanApplyCaseDao loanApplyCaseDao;
	@Autowired
	private ICaseNodeRoleService caseNodeRoleService;
	@Autowired
	private ICaseManagerProductTypeService caseManagerProductTypeService;
	@Autowired
	private IActivityLoadingService activityLoadingService;
	@Autowired
	private ILoanApplyCaseLogService loanApplyCaseLogService;
	@Autowired
	private ISysUserService sysUserService;
	@Autowired
	private ApproveConsumerSystemApi consumerSystemApi;
	@Autowired
	private McamLoanInsurancePolicyInfoMapper loanInsurancePolicyInfoMapper;
	@Autowired
	private ApproveConsumerExternalApi consumerExternalApi;
	@Autowired
	private AcLoanApplyNodeService acLoanApplyNodeService;
	@Autowired
	private LoanBasicDataConsumerApi loanBasicDataConsumerApi;
	@Autowired
	private ApproveConsumerFinancialApi consumerFinancialApi;

	@Autowired
	private IMcamLoanApplyInfoDao loanApplyInfoDao;

	@Autowired
	private ApproveConsumerProductApi consumerProductApi;

	@Autowired
	private McamHousePropertyDao mcamHousePropertyDao;
	
	@Autowired
	private ISysUserService iSysUserService;
	@Autowired
	private MarvelDecisionApi marvelDecisionApi;
	@Autowired
	private IMcamLoanApplyInfoService mcamLoanApplyInfoService;
	@Autowired
	private McamLoanApplyInfoCommonService mcamLoanApplyInfoCommonService;
	@Autowired
	private LoanRiskTipsService loanRiskTipsService;
	@Autowired
	private IProcessService processService;
	@Autowired
    private LoanInfoIDragonService loanInfoIDragonService ;
	
	/*@Autowired
	private SharedDataService sharedDataService;*/
	
	@Autowired
	private ApproveSharedDataService approveSharedDataService;
	
	@Override
	public List<LoanApplyCaseDTO> findLoanApplyCases(LoanApplyCaseDTO loanApplyCaseDTO)
			throws MarvelsBusinessException {
		// TODO 自动生成的方法存根
		loanApplyCaseDTO = loanApplyCaseDTO == null ? new LoanApplyCaseDTO() : loanApplyCaseDTO;
		PageHelper.startPage(loanApplyCaseDTO.getPageNum(), loanApplyCaseDTO.getPageSize());

		return this.loanApplyCaseDao.select(loanApplyCaseDTO);
	}
	
	@Override
	public LoanApplyCaseDTO findLoanApplyCase(Long id) throws MarvelsBusinessException {
		// TODO 自动生成的方法存根
		LoanApplyCaseDTO entity = loanApplyCaseDao.selectByPrimaryKey(id);
		if (entity == null) {
			throw new MarvelsBusinessException("获取工单跟踪失败:" + id);
		}
		return entity;
	}

	@Override
	public LoanApplyCaseDTO saveLoanApplyCase(LoanApplyCaseDTO loanApplyCase) throws MarvelsBusinessException {
		// TODO 自动生成的方法存根
		if (loanApplyCase.getId() == null) {
			add(loanApplyCase);
		} else {
			update(loanApplyCase);
		}
		return loanApplyCase;
	}

	// 新增
	private LoanApplyCaseDTO add(LoanApplyCaseDTO loanApplyCase) throws MarvelsBusinessException {
		// 效验是否已经存在
		// LoanApplyCaseDTO loanApplyCaseDTO = new LoanApplyCaseDTO();
		// loanApplyCaseDTO.setLoanId(loanApplyCase.getLoanId());
		LoanApplyCaseDTO loanApplyCaseDTO = this.loanApplyCaseDao.getEntityByLoanId(loanApplyCase.getLoanId());
		if (loanApplyCaseDTO != null) {
			throw new MarvelsBusinessException(
					"进件号[" + loanApplyCase.getLoanId() + "]姓名[" + loanApplyCase.getCustName() + "]已经存在流程中不能新增！");
		}

		loanApplyCase.setCaseId(MarvelsUtils.generateUUIDCode("CASE"));
		loanApplyCase.setStatus(1);// 草稿
		loanApplyCase.setCaseType(0);
		loanApplyCase.setDeleteFlag(0);
		Object count = this.loanApplyCaseDao.insert(loanApplyCase);
		MarvelsLogUtil.getInstance().info(loanApplyCase.getLoanId() + "工单跟踪服务新增条数:" + count);
		return loanApplyCase;
	}

	// 更新
	private LoanApplyCaseDTO update(LoanApplyCaseDTO loanApplyCase) {
		Object count = this.loanApplyCaseDao.updateByPrimaryKeySelective(loanApplyCase);
		MarvelsLogUtil.getInstance().info(loanApplyCase.getLoanId() + "工单跟踪服务更新条数:" + count);
		return loanApplyCase;
	}

	@Override
	public Integer findWaitProcessNum(List<String> roles,List<String> nodes) {
		// "您无权限查看待取件"
		if (roles == null || roles.size() == 0) {
			return 0;
		} 
		return this.loanApplyCaseDao.selectWaitProcessNum(roles,nodes);
	}

	@Override
	public List<LoanApplyCaseDTO> findLoanApplyCases(HandleProcessDTO handleProcessDTO)
			throws MarvelsBusinessException {
		// TODO 自动生成的方法存根
		List<String> nodes = findUserNodes(handleProcessDTO);
		handleProcessDTO.setNodes(nodes);
		if(nodes == null || nodes.size() == 0) {
			throw new MarvelsBusinessException("您无权限取该节点工单");
		}
		List<LoanApplyCaseDTO> loanApplyCases = this.loanApplyCaseDao.selectLoanApplyCases(handleProcessDTO);
		return loanApplyCases;
	}
	
	@Override
	public LoanApplyCaseDTO findLoanApplyCasesByLoanId(HandleProcessDTO handleProcessDTO)
			throws MarvelsBusinessException {
		// TODO 自动生成的方法存根
		List<String> nodes = findUserNodes(handleProcessDTO);
		handleProcessDTO.setNodes(nodes);
		if(nodes == null || nodes.size() == 0) {
			throw new MarvelsBusinessException("您无权限取该节点工单");
		}
		LoanApplyCaseDTO loanApplyCases = this.loanApplyCaseDao.selectLoanApplyCasesByLondId(handleProcessDTO);
		return loanApplyCases;
	}
	 
	public List<String> findUserNodes(HandleProcessDTO handleProcessDTO) throws MarvelsBusinessException {
		// 根据用户权限获取能查想节点以及查询的节点
		// TODO 自动生成的方法存根
		List<String> roleCodes = handleProcessDTO.getRoleCodes();
		List<String> queryNodes = handleProcessDTO.getQueryNodes();
		List<CaseNodeRoleDTO> caseNodeRoles = caseNodeRoleService.findCaseNodeRoles(roleCodes);
		int size = caseNodeRoles == null ? 0 : caseNodeRoles.size();
		if (size == 0) {
			return Collections.EMPTY_LIST;
		}
		List<String> nodes = new ArrayList();
		for (int i = 0; i < size; i++) {
			CaseNodeRoleDTO caseNodeRole = caseNodeRoles.get(i);
			String node = caseNodeRole.getNodeCode();
			// 是属于我查询的节点,查询节点为空表示获取所有权限下的节点
			if (queryNodes == null) {
				nodes.add(node);
			} else if (queryNodes.contains(node)) {
				nodes.add(node);
			}
		}
		return nodes;
	}

	@Override
	public LoanApplyCaseDTO pickupLoanApplyCases(LoanApplyCaseDTO loanApplyCase) throws MarvelsBusinessException {
		// 取件
		if (loanApplyCase == null || loanApplyCase.getId() == null) {
			throw new MarvelsBusinessException("取件时处理的件数据错误" + loanApplyCase);
		}
		Integer count = this.loanApplyCaseDao.transferLoanApplyCases(loanApplyCase);
		if (count == 1) {//
			return this.loanApplyCaseDao.selectByPrimaryKey(loanApplyCase.getId());
		} else {
			return null;
		}
	}

	@Transactional(timeout = 30 ,rollbackFor = Exception.class)
	public LoanApplyCaseDTO completeNode(CompleteProcessDTO completeProcessDTO) throws MarvelsBusinessException {
		// 完成当前节点任务
		String loanId = completeProcessDTO.getLoanId();
		if (org.apache.commons.lang.StringUtils.isBlank(loanId)) {
			throw new MarvelsBusinessException("贷款进件号为空:" + loanId);
		}
		// 获取流程
		LoanApplyCaseDTO caseDto = this.loanApplyCaseDao.getEntityByLoanId(loanId);
		if (caseDto == null) {
			throw new MarvelsBusinessException("无法获取流程:" + loanId);
		}
		//
		ProcessApproveDTO processApproveDto = completeProcessDTO.getProcessApproveDto();
		String processResult = processApproveDto.getProcessResult();
		// 检查是否为退回到前端
		if (MarvelsConstant.PROCESS_RESULT_RETURN_APP.equals(processResult)) {
			return2App(caseDto);
			return caseDto;
		}
		String procInstId = caseDto.getProcInstId();
		completeProcessDTO.setProcessInstanceId(procInstId);
		ActivitiNodeDTO activitiNode = new ActivitiNodeDTO();
		activitiNode.setProcessInstanceId(procInstId);
		activitiNode.setNodeCode(caseDto.getCurNodeCode());
		activitiNode.setNodeName(caseDto.getCurNodeName());
		completeProcessDTO.setCurNode(activitiNode);
		activityLoadingService.completeTask(completeProcessDTO);
		if (completeProcessDTO.getChangeNode() != null
				&& !StringUtils.isBlank(completeProcessDTO.getChangeNode().getNodeCode())) {
			// 节点流程成功
			String assignee = caseDto.getAssignee();
			
			caseDto.setPriAssignee(assignee);
			String curNodeCode = caseDto.getCurNodeCode();
			String preNodeName = caseDto.getCurNodeName();
			caseDto.setCurNodeCode(completeProcessDTO.getChangeNode().getNodeCode());
			caseDto.setCurNodeName(completeProcessDTO.getChangeNode().getNodeName());
			caseDto.setPreNodeCode(curNodeCode);
			caseDto.setPreNodeName(preNodeName);
			LoanApplyCaseLogDTO caseLogBefore = loanApplyCaseLogService.getHistoryAssigneeOfNodeCode(loanId, caseDto.getCurNodeCode());
			//如果之前有现节点就去之前节点处理人处理
			if (caseLogBefore == null) {
				caseDto.setAssignee(null);
				caseDto.setAssigneeName(null);
			}else {
				caseDto.setAssignee(caseLogBefore.getAssignee());
				caseDto.setAssigneeName(caseLogBefore.getAssigneeName());
				if(MarvelsConstant.PROCESS_RESULT_RETURN.equals(processResult)) {
					caseDto.setCaseStatus(LoanCaseStatusConstant.ZH);
				}else {
					caseDto.setCaseStatus("");
				}
			}
			UserDTO user = CacheUtils.getCacheUser();
			caseDto.setUpdatedBy(user.getUserCode());
			caseDto.setCurAssignee(assignee);//老处理人
			versionAdd(caseDto, (String) processResult);
			Integer count = loanApplyCaseDao.transferLoanApplyCases(caseDto);
			if (count != 1) {
				throw new MarvelsBusinessException("修改流程数据错误:" + count + "贷款进件号为空:" + loanId);
			}
			// 记录日志
			loanApplyCaseLogService.commCompleteCase(caseDto, (String) processResult);
			// 是否结案
			if (CaseNodeConstant.WOEND.getCode().equals(completeProcessDTO.getChangeNode())) {
				// 结案处理
				endNode(caseDto);
			}
		}
		return caseDto;
	}

	/** 退单动作case版本增加 */
	private void versionAdd(LoanApplyCaseDTO caseDto, String processResult) throws MarvelsBusinessException {
		Integer caseVersion = caseDto.getCaseVersion();
		if (caseVersion == null || (MarvelsConstant.PROCESS_RESULT_RETURN.equals(processResult)
				|| MarvelsConstant.PROCESS_RESULT_RETURN_APP.equals(processResult))) {
			caseDto.setCaseVersion(caseVersion == null ? 1 : (++caseVersion));
		}
	}

	/** 退回到APP */
	private void return2App(LoanApplyCaseDTO caseDto) throws MarvelsBusinessException {
		// 版本增
		versionAdd(caseDto, MarvelsConstant.PROCESS_RESULT_RETURN_APP);
		caseDto.setCaseStatus(LoanCaseStatusConstant.ZHAPP);
		loanApplyCaseDao.updateByPrimaryKeySelective(caseDto);
		// 记录日志
		loanApplyCaseLogService.commCompleteCase(caseDto, MarvelsConstant.PROCESS_RESULT_RETURN_APP);
	}

	@Override
	public String startFlow(McamLoanApplyInfoDTO loanApplyInfo) throws MarvelsBusinessException {
		// 开启流程
		if (loanApplyInfo == null) {
			throw new MarvelsBusinessException("进件数据不能为空");
		}
		CaseManagerProductTypeDTO ptDto = queryCaseManagerProductTypeDTO(loanApplyInfo);
		if (ptDto == null || ("A".equals(loanApplyInfo.getStatus()) && !"0".equals(loanApplyInfo.getIsGoOffline()))) {//无流程或者(线上不走线下)都为不审批
			// 简版，无流程，直接抛异常
			throw new MarvelsBusinessException(loanApplyInfo.getLoanId() + "开启流程失败" + loanApplyInfo);
		}
		// 开启实例
		String processDefinitionKey = ptDto.getActKey();
		ActivitiNodeDTO activitiNode = activityLoadingService.startProcessInstanceByKey(processDefinitionKey);
		if (activitiNode == null) {
			throw new MarvelsBusinessException(loanApplyInfo.getLoanId() + "开启流程失败" + processDefinitionKey);
		}
		String procInstId = activitiNode.getProcessInstanceId();
		//
		LoanApplyCaseDTO loanApplyCase = new LoanApplyCaseDTO();
		loanApplyCase.setActKey(processDefinitionKey);
		loanApplyCase.setActName(ptDto.getActName());
		loanApplyCase.setProcInstId(procInstId);
		loanApplyCase.setCurNodeCode(activitiNode.getNodeCode());
		loanApplyCase.setCurNodeName(activitiNode.getNodeName());
		// 保存caseDto
		initCastDTO(loanApplyInfo, loanApplyCase);
		this.saveLoanApplyCase(loanApplyCase);
		String taskId = activitiNode.getProcessTaskId();
		//通过配置转向状态
		Map varis = activityLoadingService.getVariables(taskId);
		String status=varis.get("loan_apply_status").toString(); 
		return status;
	}

	// 获取流程以及是否符合规则
	private CaseManagerProductTypeDTO queryCaseManagerProductTypeDTO(McamLoanApplyInfoDTO loanApplyInfo)
			throws MarvelsBusinessException {
		String productType = loanApplyInfo.getProductType();
		CaseManagerProductTypeDTO ptDto = new CaseManagerProductTypeDTO();
		ptDto.setProductType(productType);
		List<CaseManagerProductTypeDTO> caseManagerProductTypes = caseManagerProductTypeService
				.findCaseManagerProductTypes(ptDto);
		if (caseManagerProductTypes == null || caseManagerProductTypes.size() < 1) {
			MarvelsLogUtil.getInstance().info("无需进入流程处理loanId:" + loanApplyInfo.getLoanId() + ",产品类型:" + productType);
			return null;
		}
		// 有流程是否符合规则

		CaseManagerProductTypeDTO casePTDTO = caseManagerProductTypes.get(0);
		return casePTDTO;
	}

	// 初始化流程对象
	private void initCastDTO(McamLoanApplyInfoDTO loanApplyInfo, LoanApplyCaseDTO caseDto) {
		caseDto.setApplyAmount(loanApplyInfo.getPrincipalAmt());
		caseDto.setApplyTerms(loanApplyInfo.getApplyTerms());
		caseDto.setCaseType(0);
		caseDto.setChannel(loanApplyInfo.getChannel());
		caseDto.setChannelName(loanApplyInfo.getChannelName());
		caseDto.setCreatedBy(MarvelsConstant.SYSTEM_USER);
		caseDto.setCreatedDate(new Date());
		caseDto.setUpdatedBy(MarvelsConstant.SYSTEM_USER);
		caseDto.setUpdatedDate(new Date());
		caseDto.setCustMobile(loanApplyInfo.getMobileNo());
		caseDto.setCustCardNo(loanApplyInfo.getCustCardNo());
		caseDto.setCustName(loanApplyInfo.getCustName());
		caseDto.setLoanId(loanApplyInfo.getLoanId());
		caseDto.setProductCode(loanApplyInfo.getProductCode());
		caseDto.setProductName(loanApplyInfo.getProductName());
		caseDto.setProductType(loanApplyInfo.getProductType());
		caseDto.setProductTypeName(loanApplyInfo.getProductTypeName());
		caseDto.setEmployeeId(loanApplyInfo.getEmployeeId());
		caseDto.setEmployeeName(loanApplyInfo.getEmployeeName());
		caseDto.setPatternCode(loanApplyInfo.getPatternCode());
		caseDto.setPatternName(loanApplyInfo.getPatternName());
	}

	@Override
	public LoanApplyCaseDTO endNode(LoanApplyCaseDTO loanApplyCaseDTO) throws MarvelsBusinessException {
		// 结案处理
		if (loanApplyCaseDTO == null || StringUtils.isBlank(loanApplyCaseDTO.getLoanId())) {
			throw new MarvelsBusinessException("结案的工单不能为空");
		}
		endNodeCommon(loanApplyCaseDTO);
		// 日志关闭
		this.loanApplyCaseLogService.endCase(loanApplyCaseDTO);
		return loanApplyCaseDTO;
	}

	private LoanApplyCaseDTO endNodeCommon(LoanApplyCaseDTO loanApplyCaseDTO) throws MarvelsBusinessException {
		// 通用结案处理
		MarvelsLogUtil.getInstance().info("通用结案处理COMMON_END_NODE_loanId:" + loanApplyCaseDTO.getLoanId());
		// CASEDTO ()
		// P05
		return loanApplyCaseDTO;
	}

	@Override
	public List<LoanApplyCaseDTO> findSelfLoanApplyCases(LoanApplyCaseDTO loanApplyCaseDTO)
			throws MarvelsBusinessException {
		// 征信，审批，审计3阶段查询
		UserDTO user = CacheUtils.getCacheUser();
		loanApplyCaseDTO = loanApplyCaseDTO == null ? new LoanApplyCaseDTO() : loanApplyCaseDTO;
		loanApplyCaseDTO.setAssignee(user.getUserCode());
		PageHelper.startPage(loanApplyCaseDTO.getPageNum(), loanApplyCaseDTO.getPageSize());
		return this.loanApplyCaseDao.selectSelf(loanApplyCaseDTO);
	}

	@Override
	public List<LoanApplyCaseDTO> findLoanApplyCaseForTransfers(LoanApplyCaseDTO loanApplyCaseDTO)
			throws MarvelsBusinessException {
		// 转件查询流程
		// 查询角色有权限的节点
		String roleCode = loanApplyCaseDTO.getRoleCode();
		if (!StringUtils.isBlank(roleCode)) {// 不为空
			CaseNodeRoleDTO dto = new CaseNodeRoleDTO();
			dto.setRoleCode(roleCode);
			List<CaseNodeRoleDTO> caseNodeRoles = caseNodeRoleService.findCaseNodeRoles(dto);
			if (caseNodeRoles != null && caseNodeRoles.size() > 0) {
				List<String> nodes = new ArrayList();
				for (CaseNodeRoleDTO caseNodeRole : caseNodeRoles) {
					nodes.add(caseNodeRole.getNodeCode());
				}
				loanApplyCaseDTO.setNodeCodes(nodes);
			}
		}
		// 查询
		PageHelper.startPage(loanApplyCaseDTO.getPageNum(), loanApplyCaseDTO.getPageSize());
		List<LoanApplyCaseDTO> results = loanApplyCaseDao.selectLoanApplyCaseForTransfers(loanApplyCaseDTO);
		return results;
	}

	@Transactional(timeout = 30 ,rollbackFor = Exception.class)
	public LoanApplyCaseDTO transfersLoanApplyCase(LoanApplyCaseDTO loanApplyCaseDTO) throws MarvelsBusinessException {
		// 转件
		// 要转给
		String assignee = loanApplyCaseDTO.getAssignee();
		// 当前单所在人
		String curAssignee = loanApplyCaseDTO.getCurAssignee();
		SysUserDTO assigneeUserDto = this.sysUserService.querySysUserByUserCode(assignee);
		if (assigneeUserDto == null) {
			throw new MarvelsBusinessException(assignee + "不是系统用户");
		}
		LoanApplyCaseDTO loanCase = this.loanApplyCaseDao.getEntityByLoanId(loanApplyCaseDTO.getLoanId());
		if (loanCase == null) {
			throw new MarvelsBusinessException(loanApplyCaseDTO.getLoanId() + "审批单不存在");
		}
		String oldAssignee = loanCase.getAssignee();
		loanCase.setPriAssignee(oldAssignee);
		loanCase.setAssignee(assignee);
		loanCase.setAssigneeName(assigneeUserDto.getUserNamep());
		// Integer caseVersion = loanCase.getCaseVersion();
		// loanCase.setCaseVersion(caseVersion==null?1:(++caseVersion));
		this.loanApplyCaseDao.updateByPrimaryKeySelective(loanCase);
		// 日志
		this.loanApplyCaseLogService.commCompleteCase(loanCase, MarvelsConstant.PROCESS_RESULT_TRANSFER);
		// 修改状态
		McamLoanApplyInfoDTO loanApplyInfo = mcamLoanApplyInfoService.findMcamLoanApplyInfo(loanApplyCaseDTO.getLoanId());
		modifyStatus(loanApplyInfo);
		return loanCase;
	}
	
	// 状态流转
	private void modifyStatus(McamLoanApplyInfoDTO loanApplyInfo) throws MarvelsBusinessException {
		String status = loanApplyInfo.getStatus();
		String nextStatus = "";
		if (LoanStateConstant.Z00.equals(status)) {
			nextStatus = "Z01";
		} else if (LoanStateConstant.S01.equals(status)) {
			nextStatus = "S00";
		} else if (LoanStateConstant.C01.equals(status)) {
			nextStatus = "C00";
		}
		if (StringUtils.isNotEmpty(nextStatus)) {
			mcamLoanApplyInfoCommonService.updateMcamLoanApplyInfoStatusByLoanId(loanApplyInfo.getLoanId(), nextStatus,
					loanApplyInfo.getStatus(), null);
		}
	}

	@Override
	public LoanApplyCaseDTO findLoanApplyCase(String loanId) throws MarvelsBusinessException {
		// TODO Auto-generated method stub
		LoanApplyCaseDTO loanApplyCase = this.loanApplyCaseDao.getEntityByLoanId(loanId);
		return loanApplyCase;
	}
	/**通过客户类型获取名称
	 * @param custType
	 * @return
	 */
	private String getCustomerName(String custType) {
		try {
			MarvelsResultDTO result = loanBasicDataConsumerApi.getCustomerBasicDatas();
			Map resultMap = (Map)result.getData();
			List<Map> employList = (List<Map>)resultMap.get(MarvelsConstant.EMPLOY_TYPE_LIST);
			for(Map emp:employList) {
				String code = (String)emp.get("code");
				if(code != null && custType!=null && code.trim().equals(custType.trim())) {
					return (String)emp.get("name");
				}
			}
		} catch (MarvelsBusinessException e) {
			MarvelsLogUtil.getInstance().error("",e);
		}
		return null;
	}
	@Override
	public RiskParamsDTO getRiskParamsInfo(String loanId) throws MarvelsBusinessException {
		// 查询工单信息
		LoanApplyCaseDTO applyCaseDTO = loanApplyCaseDao.selectByLoanId(loanId);
		if (null == applyCaseDTO) {
			throw new MarvelsBusinessException("工单信息不存在");
		}
		// 查询贷款信息
		McamLoanApplyInfoDTO infoDTO = loanApplyInfoDao.selectMcamLoanApplyInfoByLoanId(loanId);
		McptProductMappedDto productMapped= new McptProductMappedDto();
		productMapped.setProductType(infoDTO.getProductType());
		productMapped.setTenor(infoDTO.getApplyTerms()+"");
		productMapped.setGrate(infoDTO.getCreditRating());
		productMapped.setChannel(infoDTO.getChannel());
		List<String> limitFundList=Arrays.asList(CommonProperties.getLimitFundList().split(","));
		productMapped.setLimitFundList(limitFundList);
		// 匹配产品信息
		MarvelsLogUtil.getInstance().info("LoanApplyCaseServiceImpl getRiskParamsInfo productMapped ==== "+productMapped);
		McptProductMappedDto mcptProductMappedDto = getProductMapped(productMapped);
		MarvelsLogUtil.getInstance().info("LoanApplyCaseServiceImpl getRiskParamsInfo productMapped ==== "+mcptProductMappedDto);
		
		List<McptCustomerTypeParamDTO> list = consumerProductApi.selectAllType();
		MarvelsLogUtil.getInstance().info("LoanApplyCaseServiceImpl getRiskParamsInfo ==="+list);
		RiskParamsDTO paramsDTO = new RiskParamsDTO();
		paramsDTO.setIsManPrice(mcptProductMappedDto.getIsManPrice());//是否人工定价
		paramsDTO.setConfirmCustTypes(list);
		paramsDTO.setLoanId(infoDTO.getLoanId());
		paramsDTO.setDecisionMoney(infoDTO.getDecisionMoney());
		//客户类型
		paramsDTO.setCustType(getCustomerName(infoDTO.getCustomerType()));
		// 查询认定客户类型参数
		McptCustomerTypeParamDTO mcptCustomerTypeParamDTO = new McptCustomerTypeParamDTO();
		mcptCustomerTypeParamDTO.setCustomerType(String.valueOf(infoDTO.getRiskCustomerType()));
		McptCustomerTypeParamDTO typeParamDTO = consumerProductApi.selectTypeById(mcptCustomerTypeParamDTO);
		if (null != typeParamDTO) {
			paramsDTO.setCustTypeCode(typeParamDTO.getCustomerType());
			paramsDTO.setIncomeRedoRatio(typeParamDTO.getIncomeRedoRatio());
		}
		paramsDTO.setSpecialRemark(infoDTO.getSpecialRemark());
		paramsDTO.setProductTypeName(infoDTO.getProductTypeName());
		paramsDTO.setApplyAmount(infoDTO.getPrincipalAmt());
		paramsDTO.setFundSourceName(infoDTO.getFundName());
		paramsDTO.setConfirmLevel(infoDTO.getCreditRating());//决策出的客户等级
		if(infoDTO.getRiskCustomerType()==null||"".equals(infoDTO.getRiskCustomerType())){
			paramsDTO.setConfirmCustType(infoDTO.getCreditRating());//认定客户等级:::为了后面能否手动更改
		}else{
			paramsDTO.setConfirmCustType(infoDTO.getRiskCustomerType());
		}
		paramsDTO.setProductType(infoDTO.getProductType());
		paramsDTO.setApprovedAmount(infoDTO.getPrincipalAmtAct()==null?new BigDecimal("0.00"):infoDTO.getPrincipalAmtAct());
		// 根据产品小类 资金源查询月费率
		McptProductFundRelationDto relationDto = new McptProductFundRelationDto();
		relationDto.setFundCode(infoDTO.getFundCode());
		relationDto.setProductCode(infoDTO.getProductCode());
		List<McptProductFundRelationDto> relationList = consumerProductApi.selectProductFundRelation(relationDto);
		if (null != relationList && relationList.size() > 0) {
			paramsDTO.setAprMonth(
					relationList.get(0).getRate().divide(new BigDecimal("12"), 2, BigDecimal.ROUND_HALF_UP));
			paramsDTO.setAprYear(relationList.get(0).getRate().setScale(2, BigDecimal.ROUND_HALF_UP));
		}
		// 查询咨询费
		McptProduct productInfo = new McptProduct();
		productInfo.setProductCode(infoDTO.getProductCode());
		McptConsultingFeeDTO consultingFeeDTO = consumerProductApi.mcptConsultingFeeDTO(productInfo);
		if (null != consultingFeeDTO) {
			paramsDTO.setConsultingFeeApr(consultingFeeDTO.getPercentage());
		}
		// 查询管理费
		McptManagementFeeDTO managementFeeDTO = consumerProductApi.selectManagementFeeByProductInfo(productInfo);
		if (null != managementFeeDTO) {
			paramsDTO.setManageFeeApr(managementFeeDTO.getPercentage());
		}
		// 进行试算
		LoanAfterInfoDTO loanAfterInfoDTO = new LoanAfterInfoDTO();
		loanAfterInfoDTO.setAmount(infoDTO.getPrincipalAmtAct()==null?new BigDecimal("0.00"):infoDTO.getPrincipalAmtAct());// 实际借款总额
		loanAfterInfoDTO.setDate(new Date());// 放款时间
		loanAfterInfoDTO.setProductCode(infoDTO.getProductCode());// 产品小类code
		paramsDTO.setProductCode(infoDTO.getProductCode());
		loanAfterInfoDTO.setTenor(infoDTO.getApplyTerms());// 期数
		loanAfterInfoDTO.setFundSource(infoDTO.getFundCode());// 资金源code
		loanAfterInfoDTO.setLoanId(infoDTO.getLoanId());// 贷款id
		LoanAfterInfoDTO resultInfo = consumerFinancialApi.loanTrial(loanAfterInfoDTO);
		if (null != resultInfo) {
			paramsDTO.setAccountAmount(resultInfo.getAviAmount());//到账金额
			paramsDTO.setCurrentLiabilities(resultInfo.getMonthlyAmount());//本笔负债
		}
		paramsDTO.setMicrofinanceLoanAmount(infoDTO.getMinLoanBal());
		paramsDTO.setLoanTerms(String.valueOf(infoDTO.getApplyTerms()));
		paramsDTO.setIdentificationOfLiabilities(infoDTO.getAffirmDebt()==null?new BigDecimal("0.00"):infoDTO.getAffirmDebt());
		paramsDTO.setApprovalConfirmationIncome(infoDTO.getAffirmIncomes()==null?new BigDecimal("0.00"):infoDTO.getAffirmIncomes());
		paramsDTO.setIncomeLiabilitiesRatio(infoDTO.getPersentIncomesDebt());
		Map<String, String> sendMap = new HashMap<>();
		sendMap.put("loanId", infoDTO.getLoanId());
		Map<String, Object> dataMap = consumerExternalApi.viewRiskInfoPositionData(sendMap);
		if (null != dataMap) {
			Object intBankNotPinshouseholds = dataMap.get("intBankNotPinshouseholds");
			List<IntBankNotPinshouseholds> intBankInfoList = null;
			if (intBankNotPinshouseholds != null) {
				intBankInfoList = (List<IntBankNotPinshouseholds>) intBankNotPinshouseholds;
			}
			// 取最近一条
			if (null != intBankInfoList && intBankInfoList.size() > 0) {
				IntBankNotPinshouseholds intBankInfo = intBankInfoList.get(0);

				if (intBankInfo != null) {
					BigDecimal creditExtensionRental = intBankInfo.getCreditExtensionRental();
					BigDecimal beenUsed = intBankInfo.getBeenUsed();
					// 信用卡使用率
					paramsDTO.setCreditCardUsageRate(beenUsed.divide(creditExtensionRental));

				}
				Object intBankCredittips = dataMap.get("intBankCredittips");
				List<IntBankCredittips> tipList = null;
				if (intBankCredittips != null) {
					tipList = (List<IntBankCredittips>) intBankCredittips;
				}
				// 取最近一条
				if (null != tipList && tipList.size() > 0) {
					IntBankCredittips tip = tipList.get(0);
					if (tip != null) {
						// 首次贷款日期
						paramsDTO.setFirstLoanTime(tip.getFirstMonth());
						// 首张信用卡申请日期
						paramsDTO
								.setFirstCreditCardMaturityDate(DateUtils.getDateYYYY_MM_DD(tip.getFirstCreditMonth()));
					}
				}
				// //获取未结清贷款信息汇总对象
				Object intBankNotCredittips = dataMap.get("intBankNotCredittips");
				List<IntBankNotCredittips> nottipList = null;
				if (intBankNotCredittips != null) {
					nottipList = (List<IntBankNotCredittips>) intBankNotCredittips;
				}
				// 取最近一条
				if (null != nottipList && nottipList.size() > 0) {
					IntBankNotCredittips tip = nottipList.get(0);
					if (tip != null) {
						// 6个月月还款额率
						BigDecimal contractAccount = tip.getBargainRental().doubleValue() == 0 ? new BigDecimal("1")
								: tip.getBargainRental();
						BigDecimal averageRefund = tip.getBargainRental().doubleValue() == 0 ? new BigDecimal("1")
								: tip.getBargainRental();
						paramsDTO.setLastSixMonthRepaymentRate(
								averageRefund.divide(contractAccount).divide(new BigDecimal("100")));
					}
				}
			}
		}

		if (PatternType.XIANXIAPRODUCT.getPatternTypeCode().equals(infoDTO.getPatternCode())) {// 线下产品
			List<McptProductFundRelationDto> productFundList = getProductFundList(infoDTO);
			paramsDTO.setFundSourceList(productFundList);
		}
		paramsDTO.setFundSourceCode(infoDTO.getFundCode());
		paramsDTO.setFundSourceName(infoDTO.getFundName());
		//获取相关限额
		McptProductType productType = new McptProductType();
		productType.setProductType(infoDTO.getProductType());
		MarvelsLogUtil.getInstance().info("LoanApplyCaseServiceImpl getRiskParamsInfo productType ==== "+productType);
		List<McptProductType> listProductType = consumerProductApi.mcptProductTypeInfo(productType);
		MarvelsLogUtil.getInstance().info("LoanApplyCaseServiceImpl getRiskParamsInfo listProductType ==== "+listProductType);
		paramsDTO.setPatternType(infoDTO.getPatternCode());
		paramsDTO.setMaxLimit( listProductType.get(0).getMaxAmount() );
		paramsDTO.setMinLimit( listProductType.get(0).getMinAmount() );
		
		String positionName = CacheUtils.getCacheUser().getPositionName();//此处调用用户查到岗位的方法，得到岗位信息，
		String type = ServerProperties.getValue(configPropertiesPath, "resource.properties", "jobs.type.permissions");
		if (StringUtils.isNotEmpty(type) && StringUtils.isNotEmpty(positionName) && type.contains(positionName)) {
			paramsDTO.setJobsType(1);
		}
		
		return paramsDTO;
	}

	/**
	 * 获取可用资金源合集
	 * 
	 * @param infoDTO
	 * @return
	 */
	public List<McptProductFundRelationDto> getProductFundList(McamLoanApplyInfoDTO infoDTO) {
		List<McptProductFundRelationDto> fundRelationDtoList = new ArrayList<>();
		String fundSource = infoDTO.getFundCode();
		if (FundSource.BSYH.getFundCode().equals(fundSource)) {// 宝生银行
			McptProductFundRelationDto fundRelationDto = new McptProductFundRelationDto();
			fundRelationDto.setFundCode(fundSource);
			fundRelationDto.setFundName(infoDTO.getFundName());
			fundRelationDtoList.add(fundRelationDto);
		} else {
			McptProductFundRelationDto fundRelationDto = new McptProductFundRelationDto();
			fundRelationDto.setProductCode(infoDTO.getProductCode());
			fundRelationDtoList = consumerProductApi.selectProductFundRelation(fundRelationDto);
			int terms = infoDTO.getApplyTerms();
			// 渤海 过滤条件
			if (terms > 24) {
				// 将渤海过滤出来
				fundRelationListFilter(fundRelationDtoList, FundSource.BHXT.getFundCode());
			}
			// ---明泰 过滤条件
			// 12个月上限是15万，12期超过15万的不能选择明泰
			// 24个月上限是18万，24期超过18万的不能选择明泰
			// 36个月上限是20万，36期超过20万的不能选择明泰
			String mtkey = FundSource.DJMT.getFundCode();
			BigDecimal principalAmtAct = infoDTO.getPrincipalAmt();
			if (terms == 12) {
				if (principalAmtAct.compareTo(new BigDecimal(150000)) > 0) {
					fundRelationListFilter(fundRelationDtoList, mtkey);
				}
			} else if (terms == 24) {
				if (principalAmtAct.compareTo(new BigDecimal(180000)) > 0) {
					fundRelationListFilter(fundRelationDtoList, mtkey);
				}
			} else if (terms == 36) {
				if (principalAmtAct.compareTo(new BigDecimal(200000)) > 0) {
					fundRelationListFilter(fundRelationDtoList, mtkey);
				}
			}
			if ("1".equals(infoDTO.getProductType())) {// 云保贷
				if (!mtLoanCheck(infoDTO.getLoanId())) {
					fundRelationListFilter(fundRelationDtoList, mtkey);
				}
			}
		}
		return fundRelationDtoList;
	}

	/**
	 * 过滤掉限制的资金源
	 * 
	 * @param list
	 * @param fundSource
	 */
	public void fundRelationListFilter(List<McptProductFundRelationDto> list, String fundSource) {
		if (null != list && list.size() > 0) {
			for (McptProductFundRelationDto fundRelationDto : list) {
				if (fundSource.equalsIgnoreCase(fundRelationDto.getFundCode())) {
					list.remove(fundRelationDto);
				}
			}
		}

	}

	/**
	 * 校验是否满足明泰资金源的要求 满足返回true 否则false
	 * 
	 * @param loanId
	 * @return
	 */
	private boolean mtLoanCheck(String loanId) {

		// 1.贷记卡信息
		Map<String, String> map = new HashMap<>();
		map.put("loanId", loanId);
		List<IntBankCreditCard> creditCardInfoList = consumerExternalApi.intBankCreditCardLoanId(map);

		// 2.保单信息 判断客户至少有一个保单生效日期距申请日期满3年且征信报告贷记卡记录中不存在贷记卡状态为正常当前逾期超过300元的记录；
		List<InsurancePolicyDTO> baodanList = loanInsurancePolicyInfoMapper.selectInsuranceByLoanId(loanId);
		boolean policyFlag = false;
		// 先判断保单是否满足至少有一个生效超过3年
		if (baodanList != null && baodanList.size() > 0) {
			for (InsurancePolicyDTO acLoanApplyBxInfo : baodanList) {
				if ("祁安保险".equals(acLoanApplyBxInfo.getInsuranceCpyName()))
					continue;
				Date bxEffectiveDate = acLoanApplyBxInfo.getInsuranceEftDate();
				if (bxEffectiveDate == null)
					continue;
				// 保单生效日
				boolean isLess = DateUtils.comparisonDate(bxEffectiveDate, new Date(), 3, Calendar.YEAR);
				if (isLess) {// 投保时间超过3年
					policyFlag = true;
					break;
				}
			}
		}

		// 判断正常状态下在贷记卡是否有逾期超过300元在记录
		boolean jdFlag = true;
		if (CollectionUtils.isNotEmpty(creditCardInfoList)) {
			for (IntBankCreditCard creditCardInfo : creditCardInfoList) {
				String accountType = creditCardInfo.getAccountType();
				BigDecimal overdueAmount = creditCardInfo.getOverdueAmount();
				if ("正常".equals(accountType) && null != overdueAmount && 300 < overdueAmount.doubleValue()) {
					jdFlag = false;
					break;
				}
			}
		}
		// 如果正常状态下在贷记卡不存在超过300元逾期且保单中存在生效超过3年在则返回true
		if (policyFlag && jdFlag) {
			return true;
		}
		return false;
	}

	/**
	 * 计算年缴纳保费 最多累计3个保单信息 规则 : 1 优良职业：认定收入=年缴纳保费*8 2 优良职业：认定收入=年缴纳保费*8 3
	 * 优良职业：认定收入=年缴纳保费*8
	 * 
	 * @param loanId
	 * @return
	 */
	@Override
	public RiskParamsDTO payPremiumAnnualPayment(RiskParamsDTO riskParamsDTO) throws MarvelsBusinessException {
		String loanId = riskParamsDTO.getLoanId();
		RiskParamsDTO paramsDTO = new RiskParamsDTO();
		McamLoanApplyInfoDTO infoDTO = loanApplyInfoDao.selectMcamLoanApplyInfoByLoanId(loanId);
		if (null == infoDTO) {
			throw new MarvelsBusinessException("贷款信息不存在");
		}
		
		if(riskParamsDTO.getApprovedAmount() == null){
			throw new MarvelsBusinessException("核定金额为空");
		}
		String productCode = infoDTO.getProductCode();
		McptProductMappedDto productMapped= new McptProductMappedDto();
		productMapped.setProductType(infoDTO.getProductType());
		productMapped.setTenor(infoDTO.getApplyTerms()+"");
		productMapped.setGrate(riskParamsDTO.getConfirmCustType());
		productMapped.setChannel(infoDTO.getChannel());
		List<String> limitFundList=Arrays.asList(CommonProperties.getLimitFundList().split(","));
		productMapped.setLimitFundList(limitFundList);
		// 匹配产品信息
		MarvelsLogUtil.getInstance().info("LoanApplyCaseServiceImpl payPremiumAnnualPayment productMapped ==== "+productMapped);
		McptProductMappedDto mcptProductMappedDto = getProductMapped(productMapped);//查询产品映射参数
		MarvelsLogUtil.getInstance().info("LoanApplyCaseServiceImpl payPremiumAnnualPayment productMapped ==== "+mcptProductMappedDto);
		if (null == mcptProductMappedDto) {
			throw new MarvelsBusinessException("未匹配到产品小类");
		} else {
			if("0".equals(mcptProductMappedDto.getIsManPrice())){//允许人工定价
				productCode = mcptProductMappedDto.getProductCode();
			}
		}
		MarvelsLogUtil.getInstance().info("LoanApplyCaseServiceImpl payPremiumAnnualPayment productCode==="+productCode);
		paramsDTO.setProductCode(productCode);
		if(riskParamsDTO.getApprovedAmount().compareTo(new BigDecimal("0"))>0){
			// 进行试算
			LoanAfterInfoDTO loanAfterInfoDTO = new LoanAfterInfoDTO();
			loanAfterInfoDTO.setAmount(riskParamsDTO.getApprovedAmount());// 实际借款总额
			loanAfterInfoDTO.setDate(new Date());// 放款时间
			loanAfterInfoDTO.setProductCode(productCode);// 产品小类code
			loanAfterInfoDTO.setTenor(infoDTO.getApplyTerms());// 期数
			loanAfterInfoDTO.setFundSource(riskParamsDTO.getFundSourceCode());// 资金源code
			loanAfterInfoDTO.setLoanId(infoDTO.getLoanId());// 贷款id
			MarvelsLogUtil.getInstance().info("LoanApplyCaseServiceImpl payPremiumAnnualPayment loanAfterInfoDTO ==== "+loanAfterInfoDTO);
			LoanAfterInfoDTO resultInfo = consumerFinancialApi.loanTrial(loanAfterInfoDTO);//贷款试算
			MarvelsLogUtil.getInstance().info("LoanApplyCaseServiceImpl payPremiumAnnualPayment resultInfo ==== "+resultInfo);
			if (null != resultInfo) {
				paramsDTO.setCurrentLiabilities(resultInfo.getMonthlyAmount());//每月应还金额
				paramsDTO.setAccountAmount(resultInfo.getAviAmount());//到手金额
			}else{
				throw new MarvelsBusinessException("试算失败");
			}
			BigDecimal actIncomes = riskParamsDTO.getApprovalConfirmationIncome();//审批认定收入
			BigDecimal actDebt = riskParamsDTO.getIdentificationOfLiabilities();//认定负债
			BigDecimal currentLiabilities = resultInfo.getMonthlyAmount();//本笔负债
			if(actIncomes.compareTo(BigDecimal.ZERO)>0){// 总收入负债比
				BigDecimal incomeLiabilitiesRatio = currentLiabilities.add(actDebt).divide(actIncomes,4,BigDecimal.ROUND_HALF_DOWN).multiply(new BigDecimal(100));
				paramsDTO.setIncomeLiabilitiesRatio(incomeLiabilitiesRatio);
			}else{
				paramsDTO.setIncomeLiabilitiesRatio(BigDecimal.ZERO);// 总收入负债比
			}
		}
		
		// 查询认定客户类型参数
		McptCustomerTypeParamDTO mcptCustomerTypeParamDTO = new McptCustomerTypeParamDTO();
		mcptCustomerTypeParamDTO.setCustomerType(riskParamsDTO.getConfirmCustType());
		McptCustomerTypeParamDTO typeParamDTO = consumerProductApi.selectTypeById(mcptCustomerTypeParamDTO);
		if (null != typeParamDTO) {
			paramsDTO.setCustTypeCode(typeParamDTO.getCustomerType());
			paramsDTO.setIncomeRedoRatio(typeParamDTO.getIncomeRedoRatio());
		}else{
			throw new MarvelsBusinessException("未匹配认定客户类型参数");
		}
		
		// 根据产品小类 资金源查询月费率
		McptProductFundRelationDto relationDto = new McptProductFundRelationDto();
		relationDto.setFundCode(riskParamsDTO.getFundSourceCode());
		relationDto.setProductCode(productCode);
		MarvelsLogUtil.getInstance().info("LoanApplyCaseServiceImpl payPremiumAnnualPayment relationDto ==== "+relationDto);
		List<McptProductFundRelationDto> relationList = consumerProductApi.selectProductFundRelation(relationDto);//查询产品映射资金源
		MarvelsLogUtil.getInstance().info("LoanApplyCaseServiceImpl payPremiumAnnualPayment relationList ==== "+relationList);
		if (null != relationList && relationList.size() > 0) {
			paramsDTO.setAprMonth(
					relationList.get(0).getRate().divide(new BigDecimal("12"), 2, BigDecimal.ROUND_HALF_UP));//计算月利率
			paramsDTO.setAprYear(relationList.get(0).getRate().setScale(2, BigDecimal.ROUND_HALF_UP));//年利率
		}
		//更新限额
		McptProductType productType = new McptProductType();
		productType.setProductType(infoDTO.getProductType());
		List<McptProductType> listProductType = consumerProductApi.mcptProductTypeInfo(productType);//查询产品大类
		paramsDTO.setMaxLimit( listProductType.get(0).getMaxAmount() );
		paramsDTO.setMinLimit( listProductType.get(0).getMinAmount() );
		//咨询费
		McptProduct mcptProduct=new McptProduct();
		mcptProduct.setProductCode(productCode);
		McptConsultingFeeDTO consultingFeeDTO = consumerProductApi.mcptConsultingFeeDTO(mcptProduct);//查询咨询费
		MarvelsLogUtil.getInstance().info("LoanApplyCaseServiceImpl payPremiumAnnualPayment consultingFeeDTO ==== "+consultingFeeDTO);
		if (null != consultingFeeDTO) {
			paramsDTO.setConsultingFeeApr(consultingFeeDTO.getPercentage());
		}
		//管理费
		MarvelsLogUtil.getInstance().info("LoanApplyCaseServiceImpl payPremiumAnnualPayment mcptProduct ==== "+mcptProduct);
		McptManagementFeeDTO managementFeeDTO = consumerProductApi.selectManagementFeeByProductInfo(mcptProduct);//查询管理费
		MarvelsLogUtil.getInstance().info("LoanApplyCaseServiceImpl payPremiumAnnualPayment managementFeeDTO ==== "+managementFeeDTO);
		if (null != managementFeeDTO) {
			paramsDTO.setManageFeeApr(managementFeeDTO.getPercentage());
		}
		return paramsDTO;
	}

	@Override
	public void updateRiskInfo(RiskParamsDTO riskParamsDTO) throws MarvelsBusinessException {
		// 更新进件信息
		// 线下
		McamLoanApplyInfoDTO applyInfoDTO = new McamLoanApplyInfoDTO();
		applyInfoDTO.setAffirmDebt(riskParamsDTO.getIdentificationOfLiabilities());
		applyInfoDTO.setCurrDebt(riskParamsDTO.getCurrentLiabilities());
		applyInfoDTO.setAffirmIncomes(riskParamsDTO.getApprovalConfirmationIncome());
		applyInfoDTO.setSpecialRemark(riskParamsDTO.getSpecialRemark());
		applyInfoDTO.setPersentIncomesDebt(riskParamsDTO.getIncomeLiabilitiesRatio());
		applyInfoDTO.setMinLoanBal(riskParamsDTO.getMicrofinanceLoanAmount());
		applyInfoDTO.setFundCode(riskParamsDTO.getFundSourceCode());
		applyInfoDTO.setFundName(riskParamsDTO.getFundSourceName());
		applyInfoDTO.setPrincipalAmtAct(riskParamsDTO.getApprovedAmount());
		applyInfoDTO.setProductCode(riskParamsDTO.getProductCode());
		UserDTO user = CacheUtils.getCacheUser();
		applyInfoDTO.setUpdatedBy(user.getUserName());
		applyInfoDTO.setUpdatedDate(new Date());
		applyInfoDTO.setLoanId(riskParamsDTO.getLoanId());
		applyInfoDTO.setCustRating(riskParamsDTO.getConfirmCustType());
		applyInfoDTO.setRiskCustomerType(riskParamsDTO.getConfirmCustType());
		int count = loanApplyInfoDao.updateApplyInfo(applyInfoDTO);
		if (count < 1) {
			throw new MarvelsBusinessException("更新贷款信息失败");
		}
		
	}

	@Autowired
	private ApprovalResultsDao approvalResultsDao;
	@Autowired
	private HousePropertyDao HousePropertyDao;
	@Override
	public RiskResultDTO trialApprovedAmount(RiskParamsDTO riskParamsDTO) throws MarvelsBusinessException {
		if(riskParamsDTO==null){
			throw new MarvelsBusinessException("传入参数为空");
		}
		if(riskParamsDTO.getFundSourceCode()==null || "".equals(riskParamsDTO.getFundSourceCode().trim())){
			throw new MarvelsBusinessException("请选择资金源");
		}
		MarvelsLogUtil.getInstance().info("LoanApplyCaseService class trialApprovedAmount method param ===="+riskParamsDTO+"====loanId ======"+riskParamsDTO.getLoanId());
		String productType = riskParamsDTO.getProductType();
		if (productType == null || "".equals(productType.trim())) {
			throw new MarvelsBusinessException("产品大类为空");
		}
		if (riskParamsDTO.getConfirmCustType() == null || "".equals(riskParamsDTO.getConfirmCustType().trim())) {
			throw new MarvelsBusinessException("请选择认定客户类型");
		}
		String patternType = riskParamsDTO.getPatternType();
		if (patternType == null || "".equals(patternType.trim())) {
			throw new MarvelsBusinessException("产品类型为空");
		}
		MarvelsLogUtil.getInstance().info("LoanApplyCaseService class trialApprovedAmount method productType ===="+productType+"----patternType==="+productType);
		RiskResultDTO riskResult = new RiskResultDTO();
		BigDecimal approveAmount = BigDecimal.ZERO;
		if("A".equals(patternType)){//线上产品走决策试算决策金额
			approveAmount = tairlAmount(riskParamsDTO);//<------
		}else if("16".equals(productType)) {// 就业贷计算核定金额
			String confirmLevel = riskParamsDTO.getConfirmLevel();
			String paramName = "APP_USER_LEVEL_" + confirmLevel;
			McsmSystemParam mcsmSystemParam = new McsmSystemParam();
			mcsmSystemParam.setParamName(paramName);
			McsmSystemParam sysResult = consumerSystemApi.paramList(mcsmSystemParam).get(0);
			String paramValue = sysResult.getParamValue();//获取参数金额APP_USER_LEVEL_客户评级
			BigDecimal act = riskParamsDTO.getApprovalConfirmationIncome();
			BigDecimal paramMon = new BigDecimal(paramValue);
			approveAmount = act.multiply(paramMon);
		}else if("8".equals(productType)){//云英贷计算核定金额
			approveAmount = yYDTrailAmount(riskParamsDTO);//<------		
		}else if("4".equals(productType)){//云房贷计算核定金额
			approveAmount = yFDCalculateSimple(riskParamsDTO);		
		}else if("5".equals(productType)){//云车贷计算核定金额
			approveAmount = yCDTrailAmount(riskParamsDTO);
		}else if("18".equals(productType)){
			
		}else{
			approveAmount = otherTrailAmount(riskParamsDTO);//其他所有产品试算核定金额
		}
		riskResult.setApprovedAmount(approveAmount);
		return riskResult;
	}

	/**其他产品试算核定金额
	 * @author 娄凯琦
	 * @date 2018年9月21日  
	 * @param riskParamsDTO
	 * @throws MarvelsBusinessException
	 */
	private BigDecimal otherTrailAmount(RiskParamsDTO riskParamsDTO) throws MarvelsBusinessException{
		McptCustomerTypeParamDTO mcptCustomerTypeParamDTO = new McptCustomerTypeParamDTO();
		mcptCustomerTypeParamDTO.setCustomerType(riskParamsDTO.getConfirmCustType());
		MarvelsLogUtil.getInstance().info("LoanApplyCaseService class otherTrailAmount method param ===="+riskParamsDTO.getConfirmCustType());
		mcptCustomerTypeParamDTO = consumerProductApi.selectTypeById(mcptCustomerTypeParamDTO);//查询客户认定类型对象
		MarvelsLogUtil.getInstance().info("LoanApplyCaseService class otherTrailAmount method result ===="+mcptCustomerTypeParamDTO);
		BigDecimal principalAmt = riskParamsDTO.getApplyAmount();//客户申请金额
		BigDecimal actIncomes = riskParamsDTO.getApprovalConfirmationIncome();//审批认定收入
		BigDecimal actDebt = riskParamsDTO.getIdentificationOfLiabilities();//认定负债
		List<BigDecimal> list = new ArrayList<BigDecimal>();
		McptProductTypeDto mcptProducTypeDto = new McptProductTypeDto();
		mcptProducTypeDto.setProductType(riskParamsDTO.getProductType());
		MarvelsLogUtil.getInstance().info("LoanApplyCaseService class otherTrailAmount method  mcptProducTypeDto param ===="+mcptProducTypeDto);
		MarvelsResultDTO marvelsResultDTO =  consumerProductApi.searchProduct(mcptProducTypeDto);
		MarvelsLogUtil.getInstance().info("LoanApplyCaseService class otherTrailAmount method  mcptProducTypeDto result ===="+marvelsResultDTO);
		if(!"success".equals(marvelsResultDTO.getCode())){
			throw new MarvelsBusinessException(marvelsResultDTO.getMessage());
		}
		List<McptProductTypeDto> mcptProducTypeDtoList = (List<McptProductTypeDto>)marvelsResultDTO.getData();
		String josnStr = JSON.toJSONString(mcptProducTypeDtoList.get(0));
		mcptProducTypeDto = JSON.toJavaObject(JSON.parseObject(josnStr), McptProductTypeDto.class);
		//获取对应产品小类和资金源的利率
		McptProductFundRelationDto relationDto = new McptProductFundRelationDto();
		relationDto.setFundCode(riskParamsDTO.getFundSourceCode());
		relationDto.setProductCode(riskParamsDTO.getProductCode());
		MarvelsLogUtil.getInstance().info("LoanApplyCaseService class otherTrailAmount method  relationDto param ===="+mcptProducTypeDto);
		List<McptProductFundRelationDto> relationList = consumerProductApi.selectProductFundRelation(relationDto);
		MarvelsLogUtil.getInstance().info("LoanApplyCaseService class otherTrailAmount method  relationDto result ===="+relationList);
		BigDecimal mRate = new BigDecimal("0");
		if (null != relationList && relationList.size() > 0) {
			mRate = relationList.get(0).getRate().divide(new BigDecimal(12), 10, BigDecimal.ROUND_HALF_UP);
		}else{
			throw new MarvelsBusinessException("产品费率为空");
		}
		//贷款期数
		Integer terms = Integer.parseInt(riskParamsDTO.getLoanTerms());
		BigDecimal fz = (actIncomes.multiply(mcptCustomerTypeParamDTO.getIncomeRedoRatio())).subtract(actDebt);	// 认定收入*认定客户类型系数-认定负债
		if(BigDecimal.ZERO.compareTo(fz)==1) fz = BigDecimal.ZERO;
		BigDecimal fm = (mRate.multiply((mRate.add(BigDecimal.ONE)).pow(terms)))
				.divide((mRate.add(BigDecimal.ONE)).pow(terms).subtract(BigDecimal.ONE), 10, BigDecimal.ROUND_HALF_UP)
				.add(riskParamsDTO.getManageFeeApr());	// [月利率（1+月利率）^期数]/[(1+月利率）^期数-1] + 管理费率
		list.add(fz.divide(fm, 10, BigDecimal.ROUND_HALF_UP)
		);	//(认定收入*认定客户类型系数-认定负债)/｛[月利率（1+月利率）^期数]/[(1+月利率）^期数-1]+管理费｝
		
		//参数1:
		list.add(actIncomes.divide(mcptCustomerTypeParamDTO.getInsuranceYearRatio(), 10, BigDecimal.ROUND_HALF_UP)
				.multiply(new BigDecimal(20)));	// 认定收入/年缴保费系数 * 30
		list.add(new BigDecimal(mcptProducTypeDto.getMaxAmount()));	// 产品大类最大额度
		list.add(principalAmt);//客户申请金额
		BigDecimal min = Collections.min(list);
		return min.divide(new BigDecimal("1000"), 0, BigDecimal.ROUND_FLOOR).multiply(new BigDecimal("1000"));
	}
	
	
	/**云车贷计算核定金额
	 * @author 娄凯琦
	 * @date 2018年9月21日  
	 * @param riskParamsDTO
	 * @return
	 * @throws MarvelsBusinessException
	 */
	private BigDecimal yCDTrailAmount(RiskParamsDTO riskParamsDTO) throws MarvelsBusinessException{
		McptCustomerTypeParamDTO mcptCustomerTypeParamDTO = new McptCustomerTypeParamDTO();
		mcptCustomerTypeParamDTO.setCustomerType(riskParamsDTO.getConfirmCustType());
		MarvelsLogUtil.getInstance().info("LoanApplyCaseService class yCDTrailAmount method param ===="+riskParamsDTO.getConfirmCustType());
		mcptCustomerTypeParamDTO = consumerProductApi.selectTypeById(mcptCustomerTypeParamDTO);//查询客户认定类型对象
		MarvelsLogUtil.getInstance().info("LoanApplyCaseService class yCDTrailAmount method result ===="+mcptCustomerTypeParamDTO);
		BigDecimal principalAmt = riskParamsDTO.getApplyAmount();//客户申请金额
		BigDecimal actIncomes = riskParamsDTO.getApprovalConfirmationIncome();//审批认定收入
		BigDecimal actDebt = riskParamsDTO.getIdentificationOfLiabilities();//认定负债
		
		//获取对应产品小类和资金源的利率
		McptProductFundRelationDto relationDto = new McptProductFundRelationDto();
		relationDto.setFundCode(riskParamsDTO.getFundSourceCode());
		relationDto.setProductCode(riskParamsDTO.getProductCode());
		List<McptProductFundRelationDto> relationList = consumerProductApi.selectProductFundRelation(relationDto);
		BigDecimal mRate = new BigDecimal("0");
		if (null != relationList && relationList.size() > 0) {
			mRate = relationList.get(0).getRate().divide(new BigDecimal(12), 10, BigDecimal.ROUND_HALF_UP);
		}else{
			throw new MarvelsBusinessException("产品费率为空");
		}
		
		BigDecimal cha = actIncomes.subtract(actDebt);//认定收入-认定负债	
		//如果 认定收入-认定负债 相同数据则改 0
		if(BigDecimal.ZERO.compareTo(cha)==1) {
			cha = BigDecimal.ZERO;
		}
		BigDecimal fz = cha.multiply(mcptCustomerTypeParamDTO.getIncomeRedoRatio());	// (认定收入-认定负债)*认定客户类型系数
		//贷款期数
		Integer terms = Integer.parseInt(riskParamsDTO.getLoanTerms());
		//mRate = 月利率   (mRate.add(BigDecimal.ONE)).pow(terms)) =月利率（1+月利率）^期数 
		BigDecimal fm = (mRate.multiply((mRate.add(BigDecimal.ONE)).pow(terms)))
				.divide((mRate.add(BigDecimal.ONE)).pow(terms).subtract(BigDecimal.ONE), 10, BigDecimal.ROUND_HALF_UP)
				.add(riskParamsDTO.getManageFeeApr());	// [月利率（1+月利率）^期数]/[(1+月利率）^期数-1] + 管理费

		
		List<BigDecimal> list = new ArrayList<BigDecimal>();
		list.add(fz.divide(fm, 10, BigDecimal.ROUND_HALF_UP)
				);	//(认定收入*认定客户类型系数-认定负债)/｛[月利率（1+月利率）^期数]/[(1+月利率）^期数-1]+管理费｝
		//参数1:
		list.add(actIncomes.divide(mcptCustomerTypeParamDTO.getCarMonthRatio(), 10, BigDecimal.ROUND_HALF_UP)
				.multiply(new BigDecimal(15)));	// 认定收入/车贷月供系数 * 15
		list.add(new BigDecimal(500000));	// 50万
		list.add(principalAmt);//客户申请金额
		BigDecimal min = Collections.min(list);
		return min.divide(new BigDecimal("1000"), 0, BigDecimal.ROUND_FLOOR).multiply(new BigDecimal("1000"));
	}
	
	/**云房贷计算审批核定金额
	 * @author 娄凯琦
	 * @date 2018年9月21日  
	 * @param riskParamsDTO
	 * @return
	 * @throws MarvelsBusinessException
	 */
	private BigDecimal yFDCalculateSimple(RiskParamsDTO riskParamsDTO) throws MarvelsBusinessException{
		String loanId = riskParamsDTO.getLoanId();
		List<McamHousePropertyDTO> list = mcamHousePropertyDao.selectByLoanId(loanId);
		//房产月供
		BigDecimal monthlyPayment = BigDecimal.ZERO;
		McamHousePropertyDTO mcamHousePropertyDTO = list.get(0);
		monthlyPayment = mcamHousePropertyDTO.getHouseLoanMthPayment();//房产月供
		DecisionMsgDTO decisionMsgDTO = new DecisionMsgDTO();
		McamLoanApplyInfoDTO mcamLoanApplyInfoDTO = loanApplyInfoDao.selectMcamLoanApplyInfoByLoanId(loanId);
		decisionMsgDTO.setLoanId(loanId);
		decisionMsgDTO.setCustIdCard(mcamLoanApplyInfoDTO.getCustCardNo());
		decisionMsgDTO.setProducType(mcamLoanApplyInfoDTO.getProductType());
		MarvelsResultDTO marvelsResultDTO = marvelDecisionApi.YFDTrailApproveAmount(decisionMsgDTO);
		if(!"success".equals(marvelsResultDTO.getCode())){
			throw new MarvelsBusinessException(marvelsResultDTO.getMessage());
		}
		MarvelsLogUtil.getInstance().info("LoanApplyCaseService class yFDCalculateSimple method marvelsResultDTO ===="+marvelsResultDTO.getData());
		String josnStr = JSON.toJSONString(marvelsResultDTO.getData());
		decisionMsgDTO = JSON.toJavaObject(JSON.parseObject(josnStr), DecisionMsgDTO.class);
		BigDecimal shAllBalance = decisionMsgDTO.getShAllBalance();//上海资信贷款余额
		//计算额度
		BigDecimal loanAmount = BigDecimal.ZERO;
		if(shAllBalance.compareTo(BigDecimal.ZERO) == 0) {
			loanAmount = monthlyPayment.multiply(new BigDecimal(15));
		}if(shAllBalance.compareTo(BigDecimal.ZERO)>0 &&shAllBalance.compareTo(new BigDecimal(60000)) <= 0) {
			loanAmount = monthlyPayment.multiply(new BigDecimal(18));
		}if(shAllBalance.compareTo(new BigDecimal(60000))>0 &&shAllBalance.compareTo(new BigDecimal(200000)) <= 0) {
			loanAmount = monthlyPayment.multiply(new BigDecimal(12));
		}
		//申请金额
		BigDecimal applyMoney = riskParamsDTO.getApplyAmount();
		//固定金额
		BigDecimal fixedAmout = new BigDecimal(100000);
		BigDecimal lastBg = loanAmount;
		if(lastBg.compareTo(applyMoney)>0) {
			lastBg = applyMoney;
		}
		if(lastBg.compareTo(fixedAmout)>0) {
			lastBg = fixedAmout;
		}
		//去掉百分位部分
		BigDecimal[] resultBgs = lastBg.divideAndRemainder(new BigDecimal(1000));
		BigDecimal resultBg = lastBg.subtract(resultBgs[1]);
//		decisionMsgDTO.setTrailAmount(resultBg);
		return resultBg;
	}
	
	/**线上产品计算审批核定金额
	 * @author 娄凯琦
	 * @date 2018年9月21日  
	 * @param riskResult
	 * @throws MarvelsBusinessException 
	 */
	private BigDecimal tairlAmount(RiskParamsDTO riskParamsDTO) throws MarvelsBusinessException{
		DecisionMsgDTO decisionMsgDTO = new DecisionMsgDTO();
		decisionMsgDTO.setLoanId(riskParamsDTO.getLoanId());
		MarvelsResultDTO  marvelsResultDTO = marvelDecisionApi.trailApproveAmount(decisionMsgDTO);//远程调用计算核定金额
		if(!"success".equals(marvelsResultDTO.getCode())){
			throw new MarvelsBusinessException(marvelsResultDTO.getMessage());
		}
		MarvelsLogUtil.getInstance().info("LoanApplyCaseService class tairlAmount method marvelsResultDTO ===="+marvelsResultDTO.getData());
		String josnStr = JSON.toJSONString(marvelsResultDTO.getData());
		decisionMsgDTO = JSON.toJavaObject(JSON.parseObject(josnStr), DecisionMsgDTO.class);
		MarvelsLogUtil.getInstance().info("LoanApplyCaseService class tairlAmount method result ===="+decisionMsgDTO);
		return decisionMsgDTO.getTrailAmount();
	}
	
	/**云英贷计算审批核定金额
	 * @author 娄凯琦
	 * @date 2018年9月21日  
	 * @param riskParamsDTO
	 * @return
	 * @throws MarvelsBusinessException
	 */
	private BigDecimal yYDTrailAmount(RiskParamsDTO riskParamsDTO)throws MarvelsBusinessException{
		BigDecimal principalAmt = riskParamsDTO.getApplyAmount();//客户申请金额
		BigDecimal actIncomes = riskParamsDTO.getApprovalConfirmationIncome();//审批认定收入
		BigDecimal actDebt = riskParamsDTO.getIdentificationOfLiabilities();//认定负债
		DecisionMsgDTO decisionMsgDTO = new DecisionMsgDTO();
		decisionMsgDTO.setLoanId(riskParamsDTO.getLoanId());
		MarvelsResultDTO  marvelsResultDTO = marvelDecisionApi.YYDTrailApproveAmount(decisionMsgDTO);//远程调用查询gjj
		if(!"success".equals(marvelsResultDTO.getCode())){
			throw new MarvelsBusinessException(marvelsResultDTO.getMessage());
		}
		MarvelsLogUtil.getInstance().info("LoanApplyCaseService class yYDTrailAmount method marvelsResultDTO ===="+marvelsResultDTO.getData());
		String josnStr = JSON.toJSONString(marvelsResultDTO.getData());
		decisionMsgDTO = JSON.toJavaObject(JSON.parseObject(josnStr), DecisionMsgDTO.class);
		List<Map<String, Object>> listgjj = decisionMsgDTO.getListgjj();
		double depositBase = 0;
		if (CollectionUtils.isNotEmpty(listgjj)) {
			Map<String, Object> map = listgjj.get(0);
			String deposit = (String) map.get("deposit_base");
			if (deposit == null && deposit =="") {
				deposit = (String) map.get("deposit_amount");
				depositBase = Double.valueOf(deposit).doubleValue() * 10 * 40;
			}else{
				depositBase = Double.valueOf(deposit).doubleValue() *40 ;
			}
			
		}
		//获取对应产品小类和资金源的利率
		McptProductFundRelationDto relationDto = new McptProductFundRelationDto();
		relationDto.setFundCode(riskParamsDTO.getFundSourceCode());
		relationDto.setProductCode(riskParamsDTO.getProductCode());
		List<McptProductFundRelationDto> relationList = consumerProductApi.selectProductFundRelation(relationDto);
		BigDecimal mRate = new BigDecimal("0");
		if (null != relationList && relationList.size() > 0) {
			mRate = relationList.get(0).getRate().divide(new BigDecimal(12), 10, BigDecimal.ROUND_HALF_UP);
		}else{
			throw new MarvelsBusinessException("产品费率为空");
		}
		
		BigDecimal cha = actIncomes.subtract(actDebt);//认定收入-认定负债	
		//如果 认定收入-认定负债 相同数据则改 0
		if(BigDecimal.ZERO.compareTo(cha)==1) {
			cha = BigDecimal.ZERO;
		}
		// 进行试算 ，计算月还款额monthPay
		McptCustomerTypeParamDTO mcptCustomerTypeParamDTO = new McptCustomerTypeParamDTO();
		mcptCustomerTypeParamDTO.setCustomerType(riskParamsDTO.getConfirmCustType());
		MarvelsLogUtil.getInstance().info("LoanApplyCaseService class yYDTrailAmount method param ===="+riskParamsDTO.getConfirmCustType());
		mcptCustomerTypeParamDTO = consumerProductApi.selectTypeById(mcptCustomerTypeParamDTO);//查询客户认定类型对象
		MarvelsLogUtil.getInstance().info("LoanApplyCaseService class yYDTrailAmount method result ===="+mcptCustomerTypeParamDTO);
		BigDecimal fz = cha.multiply(mcptCustomerTypeParamDTO.getIncomeRedoRatio());	// (认定收入-认定负债)*认定客户类型系数
		//贷款期数
		Integer terms = Integer.parseInt(riskParamsDTO.getLoanTerms());
		//mRate = 月利率   (mRate.add(BigDecimal.ONE)).pow(terms)) =月利率（1+月利率）^期数 
		BigDecimal fm = (mRate.multiply((mRate.add(BigDecimal.ONE)).pow(terms)))
				.divide((mRate.add(BigDecimal.ONE)).pow(terms).subtract(BigDecimal.ONE), 10, BigDecimal.ROUND_HALF_UP)
				.add(riskParamsDTO.getManageFeeApr());	// [月利率（1+月利率）^期数]/[(1+月利率）^期数-1] + 管理费

		List<BigDecimal> list = new ArrayList<BigDecimal>();
		BigDecimal depositBaseBas = BigDecimal.valueOf(depositBase);
		list.add(new BigDecimal(500000));	// 最高额度50万
		list.add(depositBaseBas);//公积金缴存基数
		list.add(principalAmt);//客户申请金额既借款总额
		list.add(fz.divide(fm, 10, BigDecimal.ROUND_HALF_UP));	//(认定收入-认定负债)*认定客户类型系数/｛[月利率（1+月利率）^期数]/[(1+月利率）^期数-1]+管理费｝
		BigDecimal min = Collections.min(list);//将 4个值自动排序 取最小值
		MarvelsLogUtil.getInstance().info("LoanApplyCaseService class yYDTrailAmount method BigDecimal list is:"+list+";min amount is:"+min);
//		decisionMsgDTO.setTrailAmount(min.divide(new BigDecimal("100"), 0, BigDecimal.ROUND_FLOOR).multiply(new BigDecimal("100")));
		return min.divide(new BigDecimal("100"), 0, BigDecimal.ROUND_FLOOR).multiply(new BigDecimal("100"));
	}
	
	/**云保贷核定金额计算
	 * @return
	 */
	private void calculateYBD(McamLoanApplyInfoDTO infoDTO,RiskParamsDTO riskParamsDTO, RiskResultDTO riskResult) { java.util.List<BigDecimal> ybds = new ArrayList();
		// 查询认定客户类型参数
		McptCustomerTypeParamDTO mcptCustomerTypeParamDTO = new McptCustomerTypeParamDTO();
		mcptCustomerTypeParamDTO.setCustomerType(infoDTO.getRiskCustomerType());
		McptCustomerTypeParamDTO typeParamDTO = consumerProductApi.selectTypeById(mcptCustomerTypeParamDTO);
		if(typeParamDTO!=null) {
			Integer terms = infoDTO.getApplyTerms();
			//产品设置的最大/最小金额
			Long maxLimit = riskParamsDTO.getMaxLimit();
			Long minLimit = riskParamsDTO.getMinLimit();
			//认定收入
			BigDecimal actIncomes = infoDTO.getAffirmIncomes();
			// 根据产品小类 资金源查询月费率
			McptProductFundRelationDto relationDto = new McptProductFundRelationDto();
			relationDto.setFundCode(riskParamsDTO.getChooseFundCode());
			relationDto.setProductCode(infoDTO.getProductCode());
			List<McptProductFundRelationDto> relationList = consumerProductApi.selectProductFundRelation(relationDto);
			if (null != relationList && relationList.size() > 0) {
				BigDecimal fz = (actIncomes.multiply(typeParamDTO.getIncomeRedoRatio())).subtract(infoDTO.getAffirmDebt());	// 认定收入*认定客户类型系数-认定负债
				//查询管理费
				McptProduct productInfo = new McptProduct();
				productInfo.setProductCode(infoDTO.getProductCode());
				McptManagementFeeDTO managementFeeDTO = consumerProductApi.selectManagementFeeByProductInfo(productInfo);
				BigDecimal mRate = relationList.get(0).getRate().divide(new BigDecimal(12), 10, BigDecimal.ROUND_HALF_UP);
				BigDecimal fm = (mRate.multiply((mRate.add(BigDecimal.ONE)).pow(terms)))
						.divide((mRate.add(BigDecimal.ONE)).pow(terms).subtract(BigDecimal.ONE), 10, BigDecimal.ROUND_HALF_UP)
						.add(managementFeeDTO.getPercentage());	// [月利率（1+月利率）^期数]/[(1+月利率）^期数-1] + 管理费率
				BigDecimal resultOne = fz.divide(fm, 10, BigDecimal.ROUND_HALF_UP);	
				//(认定收入*认定客户类型系数-认定负债)/｛[月利率（1+月利率）^期数]/[(1+月利率）^期数-1]+管理费｝
				ybds.add(resultOne);
			}
			ybds.add(actIncomes.divide(typeParamDTO.getInsuranceYearRatio(), 10, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(20)));	// 认定收入/年缴保费系数 * 30
			ybds.add(new BigDecimal(maxLimit));	// 产品大类最大额度
			ybds.add(infoDTO.getPrincipalAmtAct());
			//
			BigDecimal min = Collections.min(ybds);
			riskResult.setResult(riskResult.RESULT_SUCCESS);
			riskResult.setMessage("成功");
			riskResult.setApprovedAmount(min);
		}else {
			riskResult.setResult(riskResult.RESULT_ERROR);
			riskResult.setMessage("认定客户类型参数配置错误");
		}
	}
	@Override
	public RiskParamsDTO fundChangeTrial(RiskParamsDTO riskParamsDTO) throws MarvelsBusinessException {
		String loanId = riskParamsDTO.getLoanId();
		McamLoanApplyInfoDTO infoDTO = loanApplyInfoDao.selectMcamLoanApplyInfoByLoanId(loanId);
		if (null == infoDTO) {
			throw new MarvelsBusinessException("贷款信息不存在");
		}
//		if (!ProductType.YBD.getProductType().equals(infoDTO.getProductType())) {// 不是云保贷
//			throw new MarvelsBusinessException("产品不符合计算要求");
//		}
		if(riskParamsDTO.getApprovedAmount().compareTo(new BigDecimal("0"))<=0){
			throw new MarvelsBusinessException("试算金额必须大于0");
		}
		if(infoDTO.getFundCode().equals(FundSource.BSYH)){
			throw new MarvelsBusinessException("宝生银行不能更换资金源");
		}
		RiskParamsDTO paramsDTO = new RiskParamsDTO();
		// 根据产品小类 资金源查询月费率
		McptProductFundRelationDto relationDto = new McptProductFundRelationDto();
		relationDto.setFundCode(riskParamsDTO.getChooseFundCode());
		relationDto.setProductCode(infoDTO.getProductCode());
		List<McptProductFundRelationDto> relationList = consumerProductApi.selectProductFundRelation(relationDto);
		if (null != relationList && relationList.size() > 0) {
			paramsDTO.setAprMonth(
					relationList.get(0).getRate().divide(new BigDecimal("12"), 2, BigDecimal.ROUND_HALF_UP));
			paramsDTO.setAprYear(relationList.get(0).getRate().setScale(2, BigDecimal.ROUND_HALF_UP));
		} else {
			throw new MarvelsBusinessException("未匹配到对应产品映射资金源");
		}
		McptCustomerTypeParamDTO mcptCustomerTypeParamDTO = new McptCustomerTypeParamDTO();
		mcptCustomerTypeParamDTO.setCustomerType(StringUtils.isEmpty(riskParamsDTO.getConfirmCustType())?  String.valueOf(infoDTO.getRiskCustomerType()):riskParamsDTO.getConfirmCustType());
		McptCustomerTypeParamDTO typeParamDTO = consumerProductApi.selectTypeById(mcptCustomerTypeParamDTO);
		paramsDTO.setLoanId(infoDTO.getLoanId());
		if (null != typeParamDTO) {
			paramsDTO.setIncomeRedoRatio(typeParamDTO.getIncomeRedoRatio());
		} else {
			throw new MarvelsBusinessException("未匹配到对应认定客户类型参数");
		}
		// 进行试算
		LoanAfterInfoDTO loanAfterInfoDTO = new LoanAfterInfoDTO();
		loanAfterInfoDTO.setAmount(riskParamsDTO.getApprovedAmount());// 实际借款总额
		loanAfterInfoDTO.setDate(new Date());// 放款时间
		loanAfterInfoDTO.setProductCode(riskParamsDTO.getProductCode());// 产品小类code
		loanAfterInfoDTO.setTenor(infoDTO.getApplyTerms());// 期数
		loanAfterInfoDTO.setFundSource(riskParamsDTO.getChooseFundCode());// 资金源code
		loanAfterInfoDTO.setLoanId(infoDTO.getLoanId());// 贷款id
		LoanAfterInfoDTO resultInfo = consumerFinancialApi.loanTrial(loanAfterInfoDTO);
		if (null != resultInfo) {
			paramsDTO.setCurrentLiabilities(resultInfo.getMonthlyAmount());
			paramsDTO.setAccountAmount(resultInfo.getAviAmount());
		}
		return paramsDTO;
	}

	/**
	 * 获取产品小类信息
	 * 
	 * @param mcptProduct
	 * @return
	 */
	private McptProductMappedDto getProductMapped(McptProductMappedDto mcptProductMappedDto) {
		List<McptProductMappedDto> list = consumerProductApi.selectProductMappedInfo(mcptProductMappedDto);
		if (null != list && list.size() > 0) {
			return list.get(0);
		}
		return null;
	}

	@Override
	public void hungUp(HungUpConditionDTO dto) throws MarvelsBusinessException {
		McsmSystemParam param=new McsmSystemParam();
		param.setParamNames(new String[] { "NOT_LIMIT_HANG_ROLE" });
		List<McsmSystemParam> paramsRoles = consumerSystemApi.paramList(param);
		//List<McsmSystemParam> paramsMount = consumerSystemApi.paramList(new String[] { "MAX_HANG_MOUNT" });
		String[] str =null;
		if(null!=paramsRoles && paramsRoles.size()>0){
			str=paramsRoles.get(0).getParamValue().split(",");
		}
		UserDTO userDTO=CacheUtils.getCacheUser();
		SysUserDTO sysUserDTO=iSysUserService.querySysUser(userDTO.getUserId());
		List<SysUserRoleDTO> list=sysUserDTO.getRoles();
		int count = 0;
		if(null!=str){
			for (int i = 0; i < str.length; i++) {// 判断该用户是否有权限挂起
				for(SysUserRoleDTO roleDTO:list){
					if (str[i].equals(roleDTO.getRoleCode())) {
						count++;
					}
				}
			}
		}else{
			throw new MarvelsBusinessException("挂起权限设置为空");
		}
		if (count > 0) {
			int updateCount=0;
			LoanApplyCaseDTO caseDTO=new LoanApplyCaseDTO();
			if(dto.getType().equals("1")){//挂起
				//更新工单状态为挂起状态
				caseDTO.setStatus(ApplyCaseStatusConstant.HUNGUP);//挂起
				caseDTO.setHangReason(dto.getHungReason());
				caseDTO.setHangTime(new Date());
				caseDTO.setLockedName(userDTO.getUserName());
				caseDTO.setLockedUser(userDTO.getUserCode());
				caseDTO.setLoanId(dto.getLoanId());
				updateCount=loanApplyCaseDao.updateByLoanId(caseDTO);
			}else{
				caseDTO.setStatus(ApplyCaseStatusConstant.DEALING);//挂起
				caseDTO.setHangReason(dto.getHungReason());
				caseDTO.setHangTime(new Date());
				caseDTO.setLockedName(userDTO.getUserName());
				caseDTO.setLockedUser(userDTO.getUserCode());
				caseDTO.setLoanId(dto.getLoanId());
				updateCount=loanApplyCaseDao.updateByLoanId(caseDTO);
			}
			if(updateCount<1){
				throw new MarvelsBusinessException("操作失败");
			}
		}else{
			throw new MarvelsBusinessException("对不起,您没有权限操作");
		}
	}

	@Override
	public Map<String, Object> getSharedPlatformInfo(String loanId) throws MarvelsBusinessException {
		//查询手机号
		McamLoanApplyInfoDTO infoDTO=loanApplyInfoDao.selectMcamLoanApplyInfoByLoanId(loanId);
		Map<String, Object> dataMap=new HashMap<String, Object>();
		dataMap.put("mobileNo", infoDTO.getMobileNo());
		dataMap.put("custCardNo", infoDTO.getCustCardNo());
		dataMap.put("custName", infoDTO.getCustName());
//		String sharedPlatformUrl = ServerProperties.getValue(configPropertiesPath, "resource.properties", "shared_platform_url");
//		//http调用共享平台数据
//		String result="";
//		try {
//			result=HttpUtils.httpPost(sharedPlatformUrl, JSON.toJSONString(dataMap));
//		}catch (Exception e) {
//			MarvelsLogUtil.getInstance().error(">>>>共享平台数据查询异常");
//		}
//		Map<String, Object> returnMap=new HashMap<String, Object>();
//		if(StringUtils.isEmpty(result)){
//			return null;
//		}else{
//			JSONObject rsultJson=JSON.parseObject(result);
//			for(String key:rsultJson.keySet()){
//				returnMap.put(key, rsultJson.get(key));
//			}
//		}
		Map<String, Object> returnMap = approveSharedDataService.sharedDataQuery(dataMap);
		return returnMap;
	}

	/**
	 * 决策拒绝列表
	 * @param decisionRefusListDTO
	 * @return
	 * @throws MarvelsBusinessException
	 */
	@Override
	public List<Map<String, Object>> decisionRefusList(DecisionRefusListDTO decisionRefusListDTO)
			throws MarvelsBusinessException {
		try {
			PageHelper.startPage(decisionRefusListDTO.getPageNo(), decisionRefusListDTO.getPageSize());
			decisionRefusListDTO.setStatus(LoanStateConstant.SR4);
			List<Map<String, Object>> datas = loanApplyInfoDao.decisionRefusList(decisionRefusListDTO);
			for (int i = 0; i < datas.size(); i++) {
				McamLoanApplyInfoDTO data = (McamLoanApplyInfoDTO) datas.get(i);
				McamAutoDecisionWithBLOBs autoDecisionWithBLOBs = loanRiskTipsService.queryAutoDecisionData(data.getLoanId(), "1");
				data.setMcamAutoDecisionWithBLOBs(autoDecisionWithBLOBs);
			}
			return datas;
		} catch (Exception e) {
			throw new MarvelsBusinessException(e);
		}
		
	}

	/**
	 * 重新取件审批
	 * @param decisionRefusListDTO
	 * @throws MarvelsBusinessException
	 */
	@Transactional(timeout = 30 ,rollbackFor=Exception.class)
	@Override
	public void reApproval(DecisionRefusListDTO decisionRefusListDTO) throws MarvelsBusinessException {
		if(decisionRefusListDTO == null || decisionRefusListDTO.getLoanId() == null){
			throw new MarvelsBusinessException("参数缺失");
		}
		String loanId = decisionRefusListDTO.getLoanId();
		MarvelsLogUtil.getInstance().info(loanId + "开始重新取件");
		McamLoanApplyInfoDTO loanApplyInfo = loanApplyInfoDao.selectMcamLoanApplyInfoByLoanId(loanId);
		
		//3.是否存在贷款
		String applyingStatus = loanInfoIDragonService.selectCustApplyingStatus(loanApplyInfo.getCustCardNo());
		if (StringUtils.isNotEmpty(applyingStatus)) {
			applyingStatus = applyingStatus.trim();
			//3.1 判断是否处于已放款状态
			if ("D01".contains(applyingStatus)) {
				throw new MarvelsBusinessException("该用户有正在还款中的贷款");
			}
			
			//3.2 判断是否是重复提交贷款申请
			if (LoanStateEnum.APPLYING.getStates().indexOf(applyingStatus) >= 0) {
				throw new MarvelsBusinessException("该用户有正在申请的贷款");
			}
			//3.3 处于待放款状态
			throw new MarvelsBusinessException("该用户有待放款申请");
		}
		
		Object reApproval = CacheUtils.getCacheObject("reApproval_" + loanId);
		if(reApproval != null){
			throw new MarvelsBusinessException("该单正在被别人取件");
		}
		try {
			CacheUtils.cacheObject("reApproval_" + loanId, "true", 60);
			String originalFundCode = loanApplyInfo.getFundCode();
			String originalProductType = loanApplyInfo.getProductCode();
			//String originalStatus = loanApplyInfo.getStatus();
			// 进入流程
			String status = this.startFlow(loanApplyInfo); //增加case表数据     loanApplyInfo.setStatus("Z00");
			// 保存
			loanApplyInfo.setStatus(status);
			Integer count = mcamLoanApplyInfoService.updateMcamLoanApplyInfoByLoanId(loanApplyInfo);
			String acLoanStatusFundList=ServerProperties.getValue(configPropertiesPath, "resource.properties", "acLoanStatus.fund.list");
			String acLoanStatusProductList=ServerProperties.getValue(configPropertiesPath, "resource.properties", "acLoanStatus.product.list");
			if(count > 0 && (StringUtil.isEmpty(acLoanStatusFundList) || acLoanStatusFundList.indexOf("," + originalFundCode + ",")==-1) && (StringUtil.isEmpty(acLoanStatusProductList) || acLoanStatusProductList.indexOf("," + originalProductType + ",")==-1) ) {//占时停止//占时停止
				// 这里直接修改，如果用队列可能会导致后续修改不了
				loanInfoIDragonService.updateLoanStatus(loanId, status);
			}
			MarvelsLogUtil.getInstance().info(loanId + "重新取件，流程启动完成，准备自动取件");
			processService.handleZSJProcessByLoanId(loanId);
			acLoanApplyNodeService.insertSelective(loanId, ApplyNode.RE_APPROVE);
			MarvelsLogUtil.getInstance().info(loanId + "重新取件完成");
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(decisionRefusListDTO.getLoanId() + "重新取件异常", e);
			throw new MarvelsBusinessException(e.getMessage());
		} finally {
			CacheUtils.delete("reApproval_" + loanId);
		}
	}

	
	
	
}
